<template>
  <div>
    <div id="out"></div>
    <!-- :onClick通过props传入回调不传参有默认参数e，@handleClick通过emit传递没有默认参数 -->
    <components-test
      @handleClick="testFn"
      :onClick="testFn"
      :name="'234234234234'"
    />
    <input @keyup.delete="testFn" />
    pageVue3Test<br />
    {{ test.a }}<br />
    {{ refTest }}<br />
    {{ computedTest }}<br />
    hookValue: {{ testHook }}<br />
    <!-- 下方内容渲染到body下（modal）支持渲染多个 -->
    <Teleport to="body">
      <div>32423423423423423</div>
    </Teleport>
    <Teleport to="body">
      <div>342342342342423423445656767867867</div>
    </Teleport>
    <!-- id为out的div在templete中当代码执行到这里时还未渲染并且会报Cannot read property 'parentNode' of null的错误 -->
    <!-- <Teleport to="#out">
      <div>outside</div>
    </Teleport> -->
    <TextTsx />
  </div>
</template>

<script lang="ts">
import componentsTest from "../../components/components-test.vue";
import TextTsx from '../../components/textTsx'
import useTest from "../../hooks/useTest";
import {
  defineComponent,
  ref,
  reactive,
  toRefs,
  onActivated,
  onDeactivated,
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onErrorCaptured,
  onRenderTracked,
  onRenderTriggered,
  onBeforeUnmount,
  onUnmounted,
  watch,
  computed,
  watchEffect,
  getCurrentInstance,
} from "vue";

export default defineComponent({
  name: "vue3Test",
  components: {
    componentsTest,
    TextTsx
  },
  data() {
    return {
      testa: 10
    }
  },
  mounted() {
    console.log(this, this.testa, "this");
  },
  setup: () => {
    // beforeCreate 和 created在vue3中直接在setup中编写
    // 由于在执行 setup 时尚未创建组件实例，因此在 setup 选项中没有 this。这意味着，除了 props 之外，你将无法访问组件中声明的任何属性——本地状态、计算属性或方法。
    const all = getCurrentInstance(); // 获取当前实例
    console.log("aaaaaaaaaaaaaaaaa", all); // 不同于react即使有响应式依赖更新了setup也只会在刚进入组件执行一次
    let test = reactive({
      // 将对象分配为 ref 值用reactive
      a: 103333,
    });
    let refTest = ref(111); // 单个值用ref
    const { testHook } = useTest({ value: refTest });
    let computedTest = computed(() => refTest.value + "计算属性"); //计算属性
    let testFn = (e?: any) => {
      // setup中的方法需要暴露才能在模板中使用
      console.log("testFn", e);
      refTest.value = 22222;
    };

    let effect = watchEffect((onInvalidate) => {
      // watchEffect只有在回调中有使用到的相应式参数才会生效
      console.log("有依赖更新了", refTest.value);
      onInvalidate(() => {
        // 侦听器被停止时和副作用即将重新执行时的回调
        console.log("和react相比");
      });
    });
    // 停止监听（组件卸载时自动停止）
    effect();
    watch(refTest, (newValue, oldValue) => {
      // 监听回调
      console.log(newValue, oldValue);
    });

    // onActivated(() => {
    //   console.log('作为keep-alive被激活了')
    // })
    // onDeactivated(() => {
    //   console.log('作为keep-alive被停用了')
    // })
    // onErrorCaptured(() => {
    //   console.log("onErrorCaptured"); // 错误处理
    // });
    // onRenderTracked(({ key, target, type }) => {
    //   // 跟踪虚拟 DOM 重新渲染时调用
    //   console.log("onRenderTracked", { key, target, type });
    // });
    // onRenderTriggered(({ key, target, type }) => {
    //   // 当虚拟 DOM 重新渲染为 triggered.Similarly 为renderTracked，接收 debugger event 作为参数。此事件告诉你是什么操作触发了重新渲染，以及该操作的目标对象和键。
    //   console.log("onRenderTriggered", { key, target, type });
    // });
    // onBeforeMount(() => {
    //   console.log("onBeforeMount");
    // });
    // onMounted(() => {
    //   testFn();
    //   console.log("onMounted", MYPROCESS);
    //   setTimeout(() => {
    //     test.a = 1000;
    //     refTest.value = 10;
    //   });
    // });
    // onBeforeUpdate(() => {
    //   console.log("onBeforeUpdate");
    // });
    // onUpdated(() => {
    //   console.log("onUpdated");
    // });
    // onBeforeUnmount(() => {
    //   console.log("onBeforeUnmount"); // 以前的beforeDestroy
    // });
    // onUnmounted(() => {
    //   console.log("onUnmounted"); // 以前的destroyed
    // });

    return { test, refTest, testFn, computedTest, testHook }; // 暴露出来的才能用到templete模板
  },
});
</script>

<style scoped>
</style>